﻿using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace AnChao.WPF.Controls.MDI.Core
{
    public class OSUtilityHelper
    {
        public static string GetDiskID()
        {
            string strHardDiskID = "";
            //try
            //{
            //    ManagementClass mc = new ManagementClass("Win32_DiskDrive");
            //    ManagementObjectCollection moc = mc.GetInstances();
            //    foreach (ManagementObject mo in moc)
            //    {
            //        var signature = mo.Properties["signature"].Value.ToString();
            //        long drevied = 0;
            //        long.TryParse(signature, out drevied);
            //        strHardDiskID = drevied.ToString("X");
            //        break;
            //    }
            //    moc = null;
            //    mc = null;
            //}
            //catch (Exception ex)
            //{
            //    LogHelper.LogErrMsg(string.Format("获取硬盘ID失败:{0}", ex.Message));
            //}

            //if (String.IsNullOrWhiteSpace(strHardDiskID))
            {
                try
                {
                    strHardDiskID = API.GetHddInfo(0);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("API获取硬盘ID失败:{0}", ex.Message));
                }
            }
            return strHardDiskID;
        }

        public static string GetHDInfo()
        {
            string strHardDiskID = "";
            try
            {
                ManagementClass mc = new ManagementClass("Win32_DiskDrive");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    var signature = mo.Properties["signature"].Value.ToString();
                    long drevied = 0;
                    long.TryParse(signature, out drevied);
                    strHardDiskID = drevied.ToString("X");
                    break;
                }
                moc = null;
                mc = null;
            }
            catch (Exception ex)
            {
                //LogHelper.LogErrMsg(string.Format("获取硬盘ID失败:{0}", ex.Message));
            }

            return strHardDiskID;
        }

        public static string GetMachineGUID()
        {
            string machineGUID = "";
            try
            {
                IntPtr HKEY_LOCAL_MACHINE = new IntPtr(-2147483646);
                RegistryView view = RegistryView.Registry32;
                if (Environment.Is64BitOperatingSystem)
                {
                    view = RegistryView.Registry64;
                }
                SafeRegistryHandle handle = new SafeRegistryHandle(HKEY_LOCAL_MACHINE, true);//获得根节点的安全句柄
                RegistryKey subkey = RegistryKey.FromHandle(handle, view).OpenSubKey("SOFTWARE\\Microsoft\\Cryptography");//获得要访问的键
                RegistryKey key = RegistryKey.FromHandle(subkey.Handle, view);//根据键的句柄和视图获得要访问的键
                machineGUID = (string)key.GetValue("MachineGuid");
            }
            catch (Exception e)
            {
                throw new Exception(string.Format("取不到MachineGUID:{0}", e.Message));
            }

            return machineGUID;
        }

        public static string GetProcessId()
        {
            string proceddorId = "";
            System.Management.ManagementClass mc = new ManagementClass("win32_processor");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                proceddorId = mo["ProcessorId"].ToString();
            }
            return proceddorId;
        }
        public static Tuple<string, string> GetIPAndMac(string url)
        {
            string ip = null;

            try
            {
                var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
                var addresses = Dns.GetHostAddresses(httpWebRequest.Address.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped));
                if (addresses.Any())
                {
                    Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    s.Connect(addresses[0], int.Parse(httpWebRequest.Address.GetComponents(UriComponents.Port, UriFormat.SafeUnescaped)));
                    ip = (s.LocalEndPoint as IPEndPoint).Address.ToString();
                }
            }
            catch (Exception) { }

            try
            {
                if (string.IsNullOrWhiteSpace(ip) || ip == "127.0.0.1")
                {
                    ip = GetHostAddressesIp();

                    if (string.IsNullOrWhiteSpace(ip) || ip == "127.0.0.1")
                    {
                        ip = GetHostEntryIP();
                        if (string.IsNullOrWhiteSpace(ip) || ip == "127.0.0.1")
                            ip = GetManagementClassIP();
                    }
                }
            }
            catch (Exception)
            {
            }

            string mac = GetMacAddress(ip);
            return new Tuple<string, string>(ip, mac);
        }

        private static string GetMacAddress(string ip)
        {
            //获取网卡硬件地址 
            string mac = "";

            try
            {
                using (ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
                {
                    using (ManagementObjectCollection moc = mc.GetInstances())
                    {
                        foreach (ManagementObject mo in moc)
                        {
                            if ((bool)mo["IPEnabled"] == false)
                                continue;

                            string mServiceName = mo["ServiceName"] as string;
                            if (mServiceName.ToLower().Contains("vmnetadapter")
                                 || mServiceName.ToLower().Contains("ppoe")
                                 || mServiceName.ToLower().Contains("bthpan")
                                 || mServiceName.ToLower().Contains("tapvpn")
                                 || mServiceName.ToLower().Contains("ndisip")
                                 || mServiceName.ToLower().Contains("sinforvnic"))
                            {
                                continue;
                            }

                            mac = mo["MacAddress"].ToString().Replace(":", "");

                            if (!string.IsNullOrWhiteSpace(ip))
                            {
                                var ips = mo["IPAddress"] as string[];
                                if (ips != null && ips.Contains(ip))
                                    break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("获取MAC地址出错");
            }

            return mac;
        }

        private static string GetHostAddressesIp()
        {
            var IPAddressCollection = new List<IPAddress>(0);
            var Collection = Dns.GetHostAddresses(Dns.GetHostName());
            var NetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
            foreach (var MIB2Interface in NetworkInterfaces)
            {
                var IPProperties = MIB2Interface.GetIPProperties();
                var UnicastAddresses = IPProperties.UnicastAddresses;
                if (UnicastAddresses.Count > 0 && IPProperties.DhcpServerAddresses.Count > 0)
                {
                    foreach (var Unicast in UnicastAddresses)
                    {
                        if (Unicast.Address.AddressFamily != AddressFamily.InterNetworkV6)
                        {
                            if (IPAddressCollection.IndexOf(Unicast.Address) < 0)
                            {
                                IPAddressCollection.Add(Unicast.Address);
                            }
                        }
                    }
                }
            }

            return IPAddressCollection.First().ToString();
        }

        private static string GetHostEntryIP()
        {
            ///获取本地的IP地址
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                    return _IPAddress.ToString();
            }

            return "";
        }

        private static string GetManagementClassIP()
        {
            ManagementClass managementClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection managementObjectCollection = managementClass.GetInstances();
            foreach (ManagementObject managementObject in managementObjectCollection)
            {
                if ((bool)managementObject["IPEnabled"] == true)
                {
                    string[] IPAddresses = (string[])managementObject["IPAddress"];
                    if (IPAddresses.Length > 0)
                        return IPAddresses[0];
                }
            }
            return "";
        }
    }
}
